package com.snap.vseries.fragment;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.SparseArray;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.snap.vseries.AppConfig;
import com.snap.vseries.Constants;
import com.snap.vseries.R;
import com.snap.vseries.base.BaseFragment;
import com.snap.vseries.bean.ExpInfo;
import com.snap.vseries.bean.HoleInfo;
import com.snap.vseries.bean.LightBean;
import com.snap.vseries.manager.ConfigManager;
import com.snap.vseries.service.OnIntensityListener;
import com.snap.vseries.ui.ExpRunningActivity;
import com.snap.vseries.ui.widget.ChannelLayout;
import com.snap.vseries.utils.ToastUtils;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.BindViews;

/**
 * 运行中荧光曲线
 */
@SuppressLint("ValidFragment")
public class RunningIntensityFragment extends BaseFragment implements CompoundButton.OnCheckedChangeListener {
    private SparseArray<List<LightBean>> lightData;
    private final HoleInfo holeInfo;
    @BindView(R.id.chart)
    LineChart chart;
    private ExpInfo expInfo;
    @BindViews({R.id.fam_cb, R.id.vic_cb, R.id.rox_cb, R.id.cy5_cb})
    CheckBox[] checkBoxes;
    @BindView(R.id.debug1_rb)
    RadioButton debug1Rb;
    @BindView(R.id.debug2_rb)
    RadioButton debug2Rb;
    @BindView(R.id.debug3_rb)
    RadioButton debug3Rb;
    @BindView(R.id.debug_rg)
    RadioGroup debugRg;
    @BindView(R.id.group_ll)
    LinearLayout groupLl;
    @BindView(R.id.ll)
    ChannelLayout ll;
    //mode 0 展示给用户看的最终的数值
    //mode 1 最原始的荧光数值
    //mode 2 原始数值叠加倍率
    private int mode = 0;
    private String[] contents;
    private OnIntensityListener onIntensityListener = new OnIntensityListener() {
        @Override
        public void onDataReceive() {
            if (getActivity() != null && ((ExpRunningActivity) getActivity()).expController != null) {
                expInfo = ((ExpRunningActivity) getActivity()).expController.getExpInfo();
            }
            if (expInfo == null || expInfo.getLightData() == null) {
                return;
            }
            lightData = expInfo.getLightData();
            if (chart == null || chart.getData() == null || lightData == null) {
                return;
            }
            chart.post(() -> {
                LineData data = chart.getLineData();
                for (int offset = 0; offset < AppConfig.TOTAL_CHANNEL_COUNT; offset++) {
                    List<LightBean> list = lightData.get(offset + mode * 1000);
                    if (list == null) {
                        return;
                    }
                    ILineDataSet set = data.getDataSetByIndex(offset);
                    int showCount = set.getEntryCount();
                    int dataCount = list.size();
                    if (dataCount > showCount) {
                        for (int j = showCount; j < dataCount; j++) {
                            set.addEntry(new Entry(j + 1, list.get(j).getIntensity()));
                        }
                    }
                    if (set instanceof LineDataSet) {
                        if (set.getEntryCount() == 1) {
                            ((LineDataSet) set).setDrawCircles(true);
                        } else {
                            ((LineDataSet) set).setDrawCircles(false);
                        }
                    }

                    data.notifyDataChanged();
                    chart.notifyDataSetChanged();

                    resetAxis();

                    chart.invalidate();
                }
            });
        }
    };


    public RunningIntensityFragment(ExpInfo expInfo) {
        this.expInfo = expInfo;
        this.lightData = expInfo.getLightData();
        this.holeInfo = expInfo.getHoleInfo();
    }

    @Override
    protected int layoutResId() {
        return R.layout.fragment_running_amp;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        initChart();
        if (getActivity() != null && ((ExpRunningActivity) getActivity()).expController != null) {
            ((ExpRunningActivity) getActivity()).expController.setOnIntensityListener(onIntensityListener);
        }
        initView();
        initCheckBox();
        debugOrigin();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (getActivity() != null && ((ExpRunningActivity) getActivity()).expController != null) {
            ((ExpRunningActivity) getActivity()).expController.setOnIntensityListener(null);
        }
    }

    private void debugOrigin() {
        if (AppConfig.Dynamic.exp_running_debug_origin_light) {
            debugRg.setVisibility(View.VISIBLE);
            debugRg.check(R.id.debug1_rb);
            debugRg.setOnCheckedChangeListener((group, checkedId) -> {
                switch (checkedId) {
                    case R.id.debug2_rb://原始
                        mode = 1;
                        break;
                    case R.id.debug3_rb://计算倍率
                        mode = 2;
                        break;
                    default:
                        mode = 0;
                }
                reFillData();
            });
        } else {
            debugRg.setVisibility(View.GONE);
        }
    }

    private void reFillData() {
        if (chart == null || chart.getData() == null) {
            return;
        }
        LineData data = chart.getLineData();
        for (int i = 0; i < AppConfig.TOTAL_HOLE_COUNT * AppConfig.TOTAL_CHANNEL_COUNT; i++) {
            ILineDataSet set = data.getDataSetByIndex(i);
            set.clear();
            List<LightBean> list = lightData.get(i + mode * 1000);
            if (list == null) {
                continue;
            }
            for (int j = 0; j < list.size(); j++) {
                set.addEntry(new Entry(j + 1, list.get(j).getIntensity()));
            }
            if (set instanceof LineDataSet) {
                if (set.getEntryCount() == 1) {
                    ((LineDataSet) set).setDrawCircles(true);
                } else {
                    ((LineDataSet) set).setDrawCircles(false);
                }
            }
        }
        data.notifyDataChanged();
        chart.notifyDataSetChanged();

        resetAxis();

        chart.invalidate();
    }


    private void initCheckBox() {
        if (holeInfo.isFamEnable()) {
            checkBoxes[0].setChecked(true);
        }
        if (holeInfo.isVicEnable()) {
            checkBoxes[1].setChecked(true);
        }

        if (holeInfo.isRoxEnable()) {
            checkBoxes[2].setChecked(true);
        }

        if (holeInfo.isCy5Enable()) {
            checkBoxes[3].setChecked(true);
        }

        for (CheckBox checkBox : checkBoxes) {
            if (!checkBox.isChecked()) {
                checkBox.setEnabled(false);
            }
            checkBox.setOnCheckedChangeListener(this);
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        onHoleChannelChanged();
    }

    protected void onHoleChannelChanged() {
        boolean[] bs = new boolean[AppConfig.TOTAL_CHANNEL_COUNT];
        for (int i = 0; i < AppConfig.TOTAL_CHANNEL_COUNT; i++) {
            bs[i] = checkBoxes[i].isChecked();
        }
        if (chart == null || chart.getData() == null) {
            return;
        }
        chart.post(() -> {
            LineData data = chart.getLineData();
            for (int i = 0; i < bs.length; i++) {
                if (data.getDataSetByIndex(i) != null) {
                    data.getDataSetByIndex(i).setVisible(bs[i]);
                    data.getDataSetByIndex(i).setHighlightEnabled(bs[i]);

                }
            }
            data.notifyDataChanged();
            chart.notifyDataSetChanged();
            chart.invalidate();
        });
    }

    private void initView() {
        if (!AppConfig.Dynamic.custom_setting) {
            groupLl.setVisibility(View.GONE);
        }
        HoleInfo holeInfo = expInfo.getHoleInfo();
        if (holeInfo == null) {
            ToastUtils.get().showText("警告：没有通道参与实验");
            return;
        }
    }


    private void initChart() {
        //图表整体的一些设置
        chart.setDrawGridBackground(false);
        chart.getDescription().setEnabled(false);
        chart.getLegend().setEnabled(false);
        chart.setDrawBorders(false);
        chart.setMaxVisibleValueCount(0);

        //左右的两根Y轴配置
        chart.getAxisRight().setEnabled(false);
        YAxis yAxis = chart.getAxisLeft();
        yAxis.setEnabled(true);
        yAxis.setDrawAxisLine(true);
        yAxis.setDrawGridLines(true);
        yAxis.setGridColor(0xffe8e9ee);
        yAxis.setTextColor(0xff8d909f);
        yAxis.setTextSize(12f);
        yAxis.setGranularity(0.1f);

        //X轴配置
        XAxis xAxis = chart.getXAxis();
        xAxis.setEnabled(true);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setDrawAxisLine(true);
        xAxis.setDrawGridLines(true);
        xAxis.setGridColor(0xffe8e9ee);
        xAxis.setTextColor(0xff8d909f);
        xAxis.setTextSize(12f);
        xAxis.setLabelCount(14);
        xAxis.setGranularity(1);

        //操作相关
        chart.getViewPortHandler().setMinMaxScaleX(1f, 5f);
        chart.getViewPortHandler().setMinMaxScaleY(1f, 5f);
        chart.setHighlightPerDragEnabled(false);
        chart.setHighlightPerTapEnabled(false);
        chart.setTouchEnabled(true);
        chart.setDragEnabled(true);
        chart.setScaleEnabled(true);
        chart.setPinchZoom(true);

        //init data()
        List<ILineDataSet> dataSets = new ArrayList<>();
        contents = new String[]{expInfo.getFamName(), expInfo.getVicName(), expInfo.getRoxName(), expInfo.getCy5Name()};
        ll.initView(contents, holeInfo.getChannelJoinFlag());
        for (int i = 0; i < AppConfig.TOTAL_CHANNEL_COUNT; i++) {
            boolean enable = (holeInfo.getChannelJoinFlag() >> i & 0x01) == 0x01;
            LineDataSet dataSet = new LineDataSet(new ArrayList<>(), (i + 1) + "");
            dataSet.setMode(LineDataSet.Mode.LINEAR);//线的样式
            dataSet.setLineWidth(2f);//线宽
            dataSet.setDrawValues(false);
            dataSet.setDrawCircles(false);//是否画点
            dataSet.setDrawCircleHole(false);
            dataSet.setCircleRadius(2.5f);
            dataSet.setCircleColor(Constants.CHANNEL_DEFAULT_COLORS[i / AppConfig.TOTAL_HOLE_COUNT % AppConfig.TOTAL_CHANNEL_COUNT]);
            dataSet.setColor(Constants.CHANNEL_DEFAULT_COLORS[i / AppConfig.TOTAL_HOLE_COUNT % AppConfig.TOTAL_CHANNEL_COUNT]);
            dataSet.setVisible(enable);

            List<LightBean> list = lightData.get(i);
            if (list != null) {
                for (int j = 0; j < list.size(); j++) {
                    dataSet.addEntry(new Entry(j + 1, list.get(j).getIntensity()));
                }
                if (dataSet.getEntryCount() == 1) {
                    dataSet.setDrawCircles(true);
                } else {
                    dataSet.setDrawCircles(false);
                }
            }
            dataSets.add(dataSet);
        }

        LineData lineData = new LineData(dataSets);
        chart.setData(lineData);

        resetAxis();

        chart.invalidate();
    }

    private void resetAxis() {
        LineData lineData = chart.getLineData();
        XAxis xAxis = chart.getXAxis();
        YAxis yAxis = chart.getAxisLeft();

        //y:0 - setting.lightBase*2.5
        //然后动态调整 x:10的倍数
        //          y:超过base*2.5   maxValue*1.1
        int xMax = lineData.getMaxEntryCountSet().getEntryCount();
        xMax = (xMax + 9) / 10 * 10;
        xAxis.setAxisMaximum(xMax);
        xAxis.setAxisMinimum(0);

        float yInit = ConfigManager.getInstance().getSettingInfo().getLightBase() * 1.3f;
        float yMax = lineData.getYMax();
        if (yMax <= yInit) {
            yMax = yInit;
        } else {
            yMax *= 1.1f;
        }
        yAxis.setAxisMaximum(yMax);
        yAxis.setAxisMinimum(0);
    }
}
